package com.sunfeng.chap5.selectkey;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;

/**
 * 将两个不同的通道注册到相同的选择器中  解决重复消费的情况
 */
public class Test107 {

    public static void main(String[] args) throws IOException {
        ServerSocketChannel serverSocketChannel1 = ServerSocketChannel.open();
        serverSocketChannel1.bind(new InetSocketAddress("localhost", 7777));
        serverSocketChannel1.configureBlocking(false);
        ServerSocketChannel serverSocketChannel2 = ServerSocketChannel.open();
        serverSocketChannel2.bind(new InetSocketAddress("localhost", 8888));
        serverSocketChannel2.configureBlocking(false);
        Selector selector1 = Selector.open();
        SelectionKey selectionKey1 = serverSocketChannel1.register(selector1, SelectionKey.OP_ACCEPT);
        SelectionKey selectionKey2 = serverSocketChannel2.register(selector1, SelectionKey.OP_ACCEPT);
        boolean isRun=true;
        while (isRun==true) {
            // 已更新其准备就绪操作集的键的数目
            // 该数目可能为零或者非零，
            // 非零的情况就是想set2中添加SelectKey的个数,  值为零的情况是selectionKeySet2中的元素并没有更改
            int keyCount = selector1.select();
            //当前连接的keys
            Set<SelectionKey> selectionKeySet1 = selector1.keys();
            //selector.selectedKeys():向selected第一次注册的，获取后要删掉的，没连接、发送数据一次就会注入一个selectKey
            //  已就绪键集中存在的SelectionKey
            Set<SelectionKey> selectionKeySet2 = selector1.selectedKeys();
            System.out.println("keyCount"+keyCount);
            System.out.println("selectionKeySet1 size()"+selectionKeySet1.size());
            System.out.println("selectionKeySet2 size()"+selectionKeySet2.size());
            Iterator<SelectionKey> iterator = selectionKeySet2.iterator();
            while (iterator.hasNext()) {
                SelectionKey next = iterator.next();
                ServerSocketChannel serverSocketChannel = (ServerSocketChannel) next.channel();
                SocketChannel socketChannel = serverSocketChannel.accept();
                if (socketChannel == null) {
                    System.out.println("打印这条信息表明是练级8888服务器时重复消费的情况");
                    System.out.println("讲7777关联的SelectKey对应的SocketChannel通道取出来");
                    System.out.println("socketChannel为null");
                }
                InetSocketAddress localAddress = (InetSocketAddress) serverSocketChannel.getLocalAddress();
                System.out.println(localAddress.getPort() + "被客户端链接了");
                iterator.remove();
                System.out.println();
            }
        }
        serverSocketChannel1.close();
        serverSocketChannel2.close();
    }
}
